package com.gin.supermarket_inventory_system.commodity.controller;

import com.gin.common.constant.ApiPath;
import com.gin.database.validation.EntityId;
import com.gin.database.vo.response.ResPage;
import com.gin.security.Constant.Security;
import com.gin.spring.annotation.MyRestController;
import com.gin.spring.exception.BusinessException;
import com.gin.spring.vo.response.Res;
import com.gin.supermarket_inventory_system.commodity.docket.CommodityDocket;
import com.gin.supermarket_inventory_system.commodity.dto.form.CommodityAddForm;
import com.gin.supermarket_inventory_system.commodity.dto.form.CommodityUpdateForm;
import com.gin.supermarket_inventory_system.commodity.dto.param.CommodityPageParam;
import com.gin.supermarket_inventory_system.commodity.dto.vo.CommodityVo;
import com.gin.supermarket_inventory_system.commodity.entity.CommodityPo;
import com.gin.supermarket_inventory_system.commodity.service.CommodityQueryService;
import com.gin.supermarket_inventory_system.commodity.service.CommodityService;
import com.gin.supermarket_inventory_system.inventory.service.InventoryService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springdoc.core.annotations.ParameterObject;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;

import java.util.List;

/**
 *
 * @since : 2023/9/26 16:37
 * @author : ginstone
 * @version : v1.0.0
 **/
@Slf4j
@MyRestController(CommodityController.API_PREFIX)
@Tag(name = CommodityController.GROUP_NAME)
@RequiredArgsConstructor
public class CommodityController {
    /**
     *  接口路径前缀
     */
    public static final String API_PREFIX = CommodityDocket.API_PREFIX + "/info";
    /**
     *  接口文档分组名称
     */
    public static final String GROUP_NAME = "商品信息管理";
    /**
     * 本接口使用的主Service类
     */
    private final CommodityService service;
    private final CommodityQueryService commodityQueryService;
    private final InventoryService inventoryService;

    @PostMapping(ApiPath.ADD)
    @Operation(summary = "添加")
    @PreAuthorize(Security.PRE_AUTHORITY_URI_OR_ADMIN)
    public Res<CommodityVo> postAdd(
            @RequestBody @Validated CommodityAddForm form,
            @SuppressWarnings("unused") HttpServletRequest request
    ) {
        final CommodityPo po = form.toPo();
        service.save(po);
        return Res.of(new CommodityVo(po));
    }

    @PostMapping(ApiPath.DEL)
    @Operation(summary = "删除")
    @PreAuthorize(Security.PRE_AUTHORITY_URI_OR_ADMIN)
    public Res<Void> postDel(@RequestParam @EntityId(service = CommodityService.class) Long id,
                             @SuppressWarnings("unused") HttpServletRequest request) {
        // 检查是否被库存使用
        final long count = inventoryService.countByCommodityId(id);
        if (count > 0) {
            throw BusinessException.of(HttpStatus.BAD_REQUEST, String.format("该商品被 %d 条库存使用, 禁止删除", count));
        }

        service.removeById(id);
        return Res.success("删除成功");
    }

    @PostMapping(ApiPath.UPDATE)
    @Operation(summary = "修改")
    @PreAuthorize(Security.PRE_AUTHORITY_URI_OR_ADMIN)
    public Res<Void> postUpdate(
            @RequestBody @Validated CommodityUpdateForm form,
            @SuppressWarnings("unused") HttpServletRequest request
    ) {
        service.updateById(form.toPo());
        return Res.success("修改成功");
    }

    @GetMapping(ApiPath.PAGE)
    @Operation(summary = "分页查询")
    public ResPage<CommodityVo> getPage(@ParameterObject @NotNull CommodityPageParam param) {
        final ResPage<CommodityVo> pageRes = service.pageByParam(param, CommodityVo::new);

        final List<CommodityVo> data = pageRes.getData();


        commodityQueryService.fillCommodityData(data);
        return pageRes;
    }
}